# 表单，注册的，登录的
import hashlib

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Length, EqualTo, ValidationError
from models import User, db, UserInfo
from utils.constants import UserStatus
from utils.validators import phone_required


class RegisterForm(FlaskForm):

    # 验证用户名唯一
    def check_username_unique(self, field):
        # 获取数据
        username = field.data
        # 通过数据库获取数据
        user = User.query.filter_by(username=username).first()
        # 如果用户名存在，抛出异常问题
        if user:
            raise ValidationError(f"{username} 已存在，请重新注册")
        return field

    username = StringField(label='用户名', render_kw={
        'class': 'form-control input-lg',
        'placeholder': '用户名'
    }, validators=[DataRequired('请输入用户名'), phone_required, check_username_unique])
    nickname = StringField(label='昵称', render_kw={
        'class': 'form-control input-lg',
        'placeholder': '昵称'
    }, validators=[DataRequired('请输入昵称'), Length(min=2, max=20, message="昵称长度在2-20之间")])
    password = PasswordField(label='密码', render_kw={
        'class': 'form-control input-lg',
        'placeholder': '请输入密码'
    }, validators=[DataRequired('请输入密码')])
    confirm_password = PasswordField(label='确认密码', render_kw={
        'class': 'form-control input-lg',
        'placeholder': '请再次输入密码'
    }, validators=[DataRequired('请输入密码'), EqualTo('password', message="两次密码输入不一致")])

    # 注册
    def user_register(self):
        username = self.username.data
        nickname = self.nickname.data
        password = self.password.data
        # 增加到db.session
        #  新增user表
        try:
            password = hashlib.sha256(password.encode()).hexdigest()
            user_obj = User(username=username, password=password, nickname=nickname)
            db.session.add(user_obj)
            # 新增userprofile表
            profile_obj = UserInfo(username=username, user=user_obj)
            db.session.add(profile_obj)
            db.session.commit()
            return user_obj
        except Exception as e:
            print(e)
            return None


# 登录表单
class LoginForm(FlaskForm):
    username = StringField(label='用户名', render_kw={
        'class': 'form-control input-lg',
        'placeholder': '用户名'
    }, validators=[DataRequired('请输入用户名')])
    password = StringField(label='密码', render_kw={
        'class': 'form-control input-lg',
        'placeholder': '用户名'
    }, validators=[DataRequired('请输入密码')])

    # 写一个username的判断，判断用户名和密码正确
    def validate(self):
        # 获取父类的结果
        result = super().validate()
        # 获取表单的用户名和密码
        username = self.username.data
        password = self.password.data
        # 获取加密后的密码
        password = hashlib.sha256(password.encode()).hexdigest()

        if result:
            user = User.query.filter_by(username=username, password=password).first()
            # 当用户名和密码对不上
            if user is None:
                result = False
                self.username.errors = ['用户名或者是密码错误']
            # 当用户失效
            elif user.status == UserStatus.USER_IN_ACTIVE.value:
                result = False
                self.username.errors = ['用户已失效']
        return result
